import * as wuzhui from "maishu-wuzhui";

interface DropdownProps<T> {
    element: HTMLSelectElement,
    dataSource: wuzhui.DataSource<T>,
    nameField: keyof T,
    valueField: keyof T,
    value: string,
    style?: React.CSSProperties,
    className?: string,
}

export class Dropdown<T> {
    private props: DropdownProps<T>;
    private data: [T, HTMLOptionElement][] = [];
    constructor(props: DropdownProps<T>) {
        this.props = props;
        this.props.dataSource.deleted.add((sender, item) => this.on_delete(item));
        this.props.dataSource.inserted.add((sender, item, index) => this.on_insert(item, index));
        this.props.dataSource.updated.add((sender, item) => this.on_update(item));
        this.render();
    }
    on_delete(item: T) {
        for (let i = 0; i < this.data.length; i++) {
            let isSame = this.props.dataSource.isSameItem(item, this.data[0][0]);
            if (isSame) {
                this.data[i][1].remove();
                this.data.splice(i, 1);
                break;
            }
        }
    }
    on_insert(item: T, index: number) {
        if (index == null)
            index = this.props.element.options.length;

        let option = this.createOptionElement(item);
        this.props.element.options.add(option, index);
    }
    on_update(item: T) {
        let { nameField, valueField } = this.props;
        for (let i = 0; i < this.data.length; i++) {
            let isSame = this.props.dataSource.isSameItem(item, this.data[0][0]);
            if (isSame) {
                this.data[i][1].innerHTML = `${this.data[i][0][nameField]}`;
                this.data[i][1].value = `${this.data[i][0][valueField]}`;
                break;
            }
        }
    }
    private createOptionElement(item: Partial<T>) {
        let { nameField, valueField } = this.props;
        let option = document.createElement('option');
        option.innerHTML = `${item[nameField]}`;
        option.value = `${item[valueField]}`;
        if (option.value == this.props.element.value)
            option.selected = true;

        return option;
    }
    async render() {
        let { nameField, valueField } = this.props;
        let args = new wuzhui.DataSourceSelectArguments();
        let items: T[];
        let result = await this.props.dataSource.executeSelect(args);
        if (Array.isArray(result)) {
            items = result;
        }
        else {
            items = result.dataItems;
        }
        items.forEach((o, i) => {
            let item = this.createOptionElement(o);
            this.props.element.options.add(item);
            this.data[i] = [o, item];
        })
        this.props.element.value = this.props.value;
    }
}